# @String(label="Please enter the path",description="Path field") file_path
import os
import re
import Jama.Matrix
import math
from ij import IJ, WindowManager,ImagePlus,ImageStack 
from java.awt.event import MouseAdapter
from ij.gui import Roi,ImageRoi,Overlay
from java.awt import Color
import time

allFileNum =0
path='D:/test/32'
class VISoRSample:
    def __init__(self,file_path,inputrange=[]):
        self.path=file_path
        self.transforms = []
        self.inverse_transforms = []
        self.stack_spheres = []
        self.sphere = [[0, 0, 0], [0, 0, 0]]
        self.x_coefficient=0
        self.y_coefficient=0
        self.roi=[]
        self.offset=[]
        self.pixel_size=0.0
        self.angle=0
        self._info=[]
        self.output=[]
        self.nmax=inputrange[0]
        self.xmax=inputrange[1]
        self.ymax=inputrange[2]
        self.inverseoutput=[]
    def readinfo(self):
        self.sphere=[[0, 0, 0], [0, 0, 0]]
        self.stack_spheres = []
        file_object = open(os.path.join(self.path, 'info.txt'), 'rU')
        flag1=0
        flag2=0
        for line in file_object:
            line=line.rstrip('\n')
            if re.search( 'stack_spheres:',line):
                flag1 = 1
                continue
            elif re.search( 'transforms:',line):
                flag1=0
                continue
            elif flag1==1:
                if re.search('\[(.*)\]', line):
                    s = re.search('\[(.*)\]', line).group(1)
                    l = []
                    for x in s.replace("'", '').split(','):
                        l.append(float(x))
                    self.stack_spheres.append(l)
                continue

            if re.search( 'sphere:',line):
                flag2 = 1
                continue
            elif (flag2 == 1):
                s = re.search('\[(.*)\]', line).group(1)
                l = []
                for x in s.replace("'", '').split(','):
                    l.append(float(x))
                self.sphere[0] = l
                flag2 += 1
                continue
            elif (flag2 == 2):
                s = re.search('\[(.*)\]', line).group(1)
                l = []
                for x in s.replace("'", '').split(','):
                    l.append(float(x))
                self.sphere[1] = l
                flag2 = 0
                continue
       # print self.sphere
       # print self.stack_spheres
        
    def readvisor(self):
        file_object = open(os.path.join(self.path, 'visor2_lowres.txt'), 'rU')
        flag1 = 0
        flag2 = 0
        for line in file_object:
            line=line.rstrip('\n')
            if  re.search('stage:',line):
                flag1=1
                continue
            elif (flag1==1):
                flag1=2
                s=re.search(r'-*\d+\.*\d*',line).group()
                self.x_coefficient=float(s)
                continue
            elif(flag1==2):
                flag1=0
                s=re.search(r'-*\d+\.*\d*',line).group()
                self.y_coefficient=float(s)
                continue

            if re.search('channels:',line):
                flag2=1
                continue
            elif(flag2==1):
                flag2=2
                s = re.search('\[(.*)\]', line).group(1)
                for x in s.replace("'", '').split(','):
                    self.roi.append(float(x))
                continue
            elif(flag2==2):
                flag2=3
                s = re.search('\[(.*)\]', line).group(1)
                for x in s.replace("'", '').split(','):
                    self.offset.append(float(x))
            elif(flag2==3):
                flag2=4
                s = re.search('-*\d+\.*\d*', line).group()
                self.pixel_size = float(s)
                continue
            elif (flag2 == 4):
                flag2 = 0
                s = re.search(r'-*\d+\.*\d*', line).group()
                self.angle = float(s)
                continue

    def readtransforms(self):
        self.transforms=[]
        self.inverse_transforms=[]
        path=os.path.join(self.path, 'transforms')
        fileNum = 0
        for lists in os.listdir(path):
            file_object=open(os.path.join(path, lists),'rU')
            transform=[]
            changetransforms=[]
            for line in file_object:
                line = line.rstrip('\n')
                if re.search('^Parameters:', line):
                    s = re.findall(r'-*\d+\.*\d*', line)
                    for x in s:
                        x=x.replace("'", '')
                        transform.append(float(x))
                    for i in range(3):
                        changetransforms.append(transform[3*i])
                        changetransforms.append(transform[3*i+1])
                        changetransforms.append(transform[3*i+2])
                        changetransforms.append(transform[i+9])
                    self.transforms.append(changetransforms)
                    #print changetransforms
            fileNum = fileNum + 1 
            #print self.transforms[fileNum-1]
        for i in range(fileNum):
            transforms = self.transforms[i]
            matrix33 = []
            matrix13 = []
            for t in range(int(len(transforms) / 4)):
                l = []
                l.append(transforms[4 * t])
                l.append(transforms[4 * t + 1])
                l.append(transforms[4 * t + 2])
                matrix33.append(l)
                n = []
                n.append(transforms[4 * t + 3])
                matrix13.append(n)
            #print matrix33
            #print matrix13
            a = Jama.Matrix(matrix33)
            b = Jama.Matrix(matrix13)
            inversematrix33 = a.inverse()
            inversematrix13 = inversematrix33.times(b)
            inversematrix13 = inversematrix13.times(-1)
            #print inversematrix33
            #print inversematrix13
            inversetransforms = []
            for t in range(int(len(transforms) / 4)):
                inversetransforms.append(inversematrix33.get(t, 0))
                inversetransforms.append(inversematrix33.get(t, 1))
                inversetransforms.append(inversematrix33.get(t, 2))
                inversetransforms.append(inversematrix13.get(t, 0))
            self.inverse_transforms.append(inversetransforms)
            #print self.inverse_transforms[i]
            
        
            
         

    def getinverseclickimage(self,i,input=[]):
    	self.inverseoutput=[]
        mharange=[self.xmax,self.ymax,self.nmax]
        x1=input[0]
        y1=input[1]
        n1=input[2]
        physiccoordinate=0.0
        inversetransforms=[]
        inversetransforms=self.inverse_transforms[i]
        for t in range(int(len(inversetransforms)/4)):
            physiccoordinate=(x1*inversetransforms[4*t]+y1*inversetransforms[4*t+1]+n1*inversetransforms[4*t+2]+inversetransforms[4*t+3])
            #print transforms[4*t],transforms[4*t+1],transforms[4*t+2],transforms[4*t+3]
            #print physiccoordinate
            self.inverseoutput.append(math.floor((physiccoordinate-self.sphere[0][t])*mharange[t]/(self.sphere[1][t]-self.sphere[0][t])))
        
            
    
    def getclickimage(self,input=[]):
    	self.output=[]
        mharange = [self.xmax, self.ymax, self.nmax]
        i=0
        x1 = input[0]*(self.sphere[1][0]-self.sphere[0][0])/mharange[0]+self.sphere[0][0]
        y1 = input[1]*(self.sphere[1][1]-self.sphere[0][1])/mharange[1]+self.sphere[0][1]
        z1 = input[2]*(self.sphere[1][2]-self.sphere[0][2])/mharange[2]+self.sphere[0][2]
       # print x1,y1,z1
        for t in range(int(len(self.stack_spheres)/2)):
            if (self.stack_spheres[2*t][1]<y1 and y1<self.stack_spheres[2*t+1][1]):
                i=t
                #print self.stack_spheres[2*t][1],self.stack_spheres[2*t+1][1]
       # print i
       
        transforms = []
        transforms = self.transforms[i]
       # print transforms
        for t in range(int(len(transforms) / 4)):
            self.output.append(math.ceil(
                x1 * transforms[4 * t] + y1 * transforms[4 * t + 1] + z1 * transforms[4 * t + 2] +
                transforms[4 * t + 3]))
        self.output.append(i)

class VISoRSampleData:
    def __init__(self,file_path):
        self.path=file_path
        self.caption=""
        self.exposure=0.0
        self.image_height = 0.0
        self.images=""
        self.lefttop_x = 0.0
        self.lefttop_y = 0.0
        self.lefttop_z= 0.0
        self.max_volts=0.0
        self.move_y=0
        self.pixel_size=0.0
        self.power=0
        self.rightbottom_x=0.0
        self.rightbottom_y=0.0
        self.rightbottom_z=0.0
        self.slices_index=0
        self.slides_index=0
        self.velocity=0.0
        self.version=""
        self.volts_offset=0.0
        self.wave_length=0
    def readflsm(self):
        files=os.listdir(self.path)
        for file in files:
            if not os.path.isdir(file):
                i=[]
                i=os.path.splitext(file)
                if i[1] == '.flsm':
                    file_object = open(os.path.join(self.path, file), 'rU')
                    for line in file_object:
                        line = line.rstrip('\n')
                        if re.search('caption', line):
                            s = re.search(r'\:.+\"', line).group()
                            t = re.search(r'\".+\"', s).group()
                            self.caption = t[1:-1]
                        elif re.search('exposure', line):
                            s = re.search(r'\:.+\"', line).group()
                            t = re.search(r'\".+\"', s).group()
                            self.exposure = float(t[1:-1])
                        elif re.search('image_height', line):
                            s = re.search(r'\:.+\"', line).group()
                            t = re.search(r'\".+\"', s).group()
                            self.image_height = float(t[1:-1])
                        elif re.search('images', line):
                            s = re.search(r'\:.+\"', line).group()
                            t = re.search(r'\".+\"', s).group()
                            self.images = t[1:-1]
                        elif re.search('lefttop_x', line):
                            s = re.search(r'\:.+\"', line).group()
                            t = re.search(r'\".+\"', s).group()
                            self.lefttop_x = float(t[1:-1])
                        elif re.search('lefttop_y', line):
                            s = re.search(r'\:.+\"', line).group()
                            t = re.search(r'\".+\"', s).group()
                            self.lefttop_y = float(t[1:-1])
                        elif re.search('lefttop_z', line):
                            s = re.search(r'\:.+\"', line).group()
                            t = re.search(r'\".+\"', s).group()
                            self.lefttop_z = float(t[1:-1])
                        elif re.search('max_volts', line):
                            s = re.search(r'\:.+\"', line).group()
                            t = re.search(r'\".+\"', s).group()
                            self.max_volts = float(t[1:-1])
                        elif re.search('move_y', line):
                            s = re.search(r'\:.+\"', line).group()
                            t = re.search(r'\".+\"', s).group()
                            self.move_y = float(t[1:-1])
                        elif re.search('pixel_size', line):
                            s = re.search(r'\:.+\"', line).group()
                            t = re.search(r'\".+\"', s).group()
                            self.pixel_size = float(t[1:-1])
                        elif re.search('power', line):
                            s = re.search(r'\:.+\"', line).group()
                            t = re.search(r'\".+\"', s).group()
                            self.power = float(t[1:-1])
                        elif re.search('rightbottom_x', line):
                            s = re.search(r'\:.+\"', line).group()
                            t = re.search(r'\".+\"', s).group()
                            self.rightbottom_x = float(t[1:-1])
                        elif re.search('rightbottom_y', line):
                            s = re.search(r'\:.+\"', line).group()
                            t = re.search(r'\".+\"', s).group()
                            self.rightbottom_y = float(t[1:-1])
                        elif re.search('rightbottom_z', line):
                            s = re.search(r'\:.+\"', line).group()
                            t = re.search(r'\".+\"', s).group()
                            self.rightbottom_z = float(t[1:-1])
                        elif re.search('slices_index', line):
                            s = re.search(r'\:.+\"', line).group()
                            t = re.search(r'\".+\"', s).group()
                            self.slices_index = float(t[1:-1])
                        elif re.search('slides_index', line):
                            s = re.search(r'\:.+\"', line).group()
                            t = re.search(r'\".+\"', s).group()
                            self.slides_index = float(t[1:-1])
                        elif re.search('velocity', line):
                            s = re.search(r'\:.+\"', line).group()
                            t = re.search(r'\".+\"', s).group()
                            self.velocity = float(t[1:-1])
                        elif re.search('version', line):
                            s = re.search(r'\:.+\"', line).group()
                            t = re.search(r'\".+\"', s).group()
                            self.version = t[1:-1]
                        elif re.search('volts_offset', line):
                            s = re.search(r'\:.+\"', line).group()
                            t = re.search(r'\".+\"', s).group()
                            self.volts_offset = float(t[1:-1])
                        elif re.search('wave_length', line):
                            s = re.search(r'\:.+\"', line).group()
                            t = re.search(r'\".+\"', s).group()
                            self.wave_length = float(t[1:-1])


def doSomething(imp,canvas):
	global n
	global imp2
	global ov
	global ov2
	global test
	global x1
	global y1
	p = canvas.getCursorLoc()
	x1 = int(p.x)
	y1 = int(p.y)
	ov.clear()
	roi=Roi(x1-10, y1-10, 20, 20)
	roi.setStrokeColor(Color.red)
	ov.add(roi)
	imp.setOverlay(ov)  
	imp.updateAndDraw(); 
	if n==0:
		IJ.openImage()                 
		imp2=IJ.getImage()
		win = imp2.getWindow()
		win.getCanvas().addMouseListener(listener2)
		IJ.runPlugIn("ij.plugin.Zoom","scale")
	n=imp.getZ()
	test.getclickimage([x1,y1,imp.getZ()])
	ov2.clear()
	roi=Roi(int(test.output[0])-10, int(test.output[1])-10, 20, 20)
	roi.setStrokeColor(Color.red)
	ov2.add(roi)
	imp2.setOverlay(ov2)  
	imp2.updateAndDraw(); 
	imp2.setT(int(test.output[2]))
	imp2.setZ(int(test.output[3])+1)
	print x1,y1,imp.getZ()
	print test.output[0],test.output[1],test.output[2],test.output[3]

def doSomething2(imp2,canvas):
	global imp
	global ov
	global ov2
	global test
	global x2
	global y2
	p = canvas.getCursorLoc()
	x2 = int(p.x)
	y2 = int(p.y)
	ov2.clear()
	roi=Roi(x2-10, y2-10, 20, 20)
	roi.setStrokeColor(Color.red)
	ov2.add(roi)
	imp2.setOverlay(ov2)  
	imp2.updateAndDraw()
	test.getinverseclickimage(imp2.getZ()-1,[x2,y2,imp2.getT()])
	ov.clear()
	roi=Roi(int(test.inverseoutput[0])-10, int(test.inverseoutput[1])-10, 20, 20)
	roi.setStrokeColor(Color.red)
	ov.add(roi)
	imp.setOverlay(ov)  
	imp.updateAndDraw()
	imp.setZ(int(test.inverseoutput[2]))
	print imp2.getZ()-1,x2,y2,imp2.getT()
	print test.inverseoutput[0],test.inverseoutput[1],test.inverseoutput[2]
	
class ML(MouseAdapter):
	def mousePressed(self, event):
		canvas = event.getSource()
		imp = canvas.getImage()
		doSomething(imp,canvas)

class ML2(MouseAdapter):
	def mousePressed(self, event):
		canvas = event.getSource()
		imp2 = canvas.getImage()
		doSomething2(imp2,canvas)


#test=VISoRSample(file_path,[184,3348,2550])
#test.readinfo()
#test.readtransforms()
#test.getinverseclickimage(2,[755,398,958])
#print test.inverseoutput[0],test.inverseoutput[1],test.inverseoutput[2]
#test.getclickimage([1500,1200,92])
#print test.output[0],test.output[1],test.output[2],test.output[3]
x1=0
x2=0
y1=0
y2=0
imp2=[]
IJ.openImage()                 
imp=IJ.getImage()
test=VISoRSample(file_path,[imp.getNSlices(),imp.width,imp.height])
test.readinfo()
test.readtransforms()
listener = ML()
listener2 = ML2()
IJ.runPlugIn("ij.plugin.Zoom","scale")
IJ.runPlugIn("ij.plugin.frame.ContrastAdjuster","")
win = imp.getWindow()
win.getCanvas().addMouseListener(listener)
n=0
ov=Overlay()
ov2=Overlay()

start=time.time()

while WindowManager.getImageCount()>0:
	while (time.time()-start > 0.2):
		start=time.time()
		imp3=IJ.getImage()
		if re.findall(".mha",imp3.title):
			if imp2!=[]:
				test.getclickimage([x1,y1,imp.getZ()])
				ov2.clear()
				roi=Roi(int(test.output[0])-10, int(test.output[1])-10, 20, 20)
				roi.setStrokeColor(Color.red)
				ov2.add(roi)
				imp2.setOverlay(ov2)  
				imp2.updateAndDraw(); 
				imp2.setT(int(test.output[2]))
				imp2.setZ(int(test.output[3])-1)
		if re.findall(".tiff",imp3.title):
			test.getinverseclickimage(imp2.getZ()-1,[x2,y2,imp2.getT()])
			ov.clear()
			roi=Roi(int(test.inverseoutput[0])-10, int(test.inverseoutput[1])-10, 20, 20)
			roi.setStrokeColor(Color.red)
			ov.add(roi)
			imp.setOverlay(ov)  
			imp.updateAndDraw()
			imp.setZ(int(test.inverseoutput[2]))

